using System;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.AvalonEdit;
using Microsoft.Xaml.Behaviors;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Document;
using System.Xml;
using System.IO;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using System.Reflection;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Text.RegularExpressions;
using AvalonEditDemo.Services;
using ICSharpCode.AvalonEdit.CodeCompletion;
using ICSharpCode.AvalonEdit.Editing;
using System.Linq;

namespace AvalonEditDemo.Services
{
    /// <summary>
    /// AvalonEdit文本绑定行为，实现AvalonEdit编辑器的文本与ViewModel属性的双向绑定
    /// 由于AvalonEdit不是标准的WPF控件，需要通过Behavior实现数据绑定
    /// </summary>
    public class TextEditorBindingBehavior : Behavior<TextEditor>
    {
        /// <summary>
        /// 定义可绑定的Text依赖属性
        /// </summary>
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TextEditorBindingBehavior),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextChanged));

        /// <summary>
        /// 获取或设置要绑定的文本
        /// </summary>
        public string Text
        {
            get => (string)GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        /// <summary>
        /// 在行为附加到编辑器时调用
        /// 添加TextChanged事件处理
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.TextChanged += EditorTextChanged;
        }

        /// <summary>
        /// 在行为从编辑器分离时调用
        /// 移除事件处理器以防止内存泄漏
        /// </summary>
        protected override void OnDetaching()
        {
            AssociatedObject.TextChanged -= EditorTextChanged;
            base.OnDetaching();
        }

        /// <summary>
        /// 当编辑器文本变化时，更新绑定属性
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void EditorTextChanged(object sender, EventArgs e)
        {
            if (sender is TextEditor editor)
            {
                Text = editor.Text;
            }
        }

        /// <summary>
        /// 当绑定的Text属性变化时，更新编辑器文本
        /// </summary>
        /// <param name="d">依赖对象</param>
        /// <param name="e">事件参数</param>
        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextEditorBindingBehavior behavior && behavior.AssociatedObject != null)
            {
                string newText = (string)e.NewValue;
                if (behavior.AssociatedObject.Text != newText)
                {
                    behavior.AssociatedObject.Text = newText ?? string.Empty;
                }
            }
        }
    }

    /// <summary>
    /// 自动补全括号行为，当用户输入左括号时自动添加右括号
    /// 支持小括号、中括号、大括号、单引号和双引号
    /// </summary>
    public class BracketCompletionBehavior : Behavior<TextEditor>
    {
        /// <summary>
        /// 在行为附加到编辑器时调用
        /// 添加按键预处理事件
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.TextArea.PreviewKeyDown += TextArea_PreviewKeyDown;
        }

        /// <summary>
        /// 在行为从编辑器分离时调用
        /// 移除事件处理器
        /// </summary>
        protected override void OnDetaching()
        {
            AssociatedObject.TextArea.PreviewKeyDown -= TextArea_PreviewKeyDown;
            base.OnDetaching();
        }

        /// <summary>
        /// 处理按键事件，检测是否需要自动补全括号
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">按键事件参数</param>
        private void TextArea_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (AutoCompleteBracket(e))
            {
                e.Handled = true;
            }
        }

        /// <summary>
        /// 根据按键自动补全相应的括号
        /// </summary>
        /// <param name="e">按键事件参数</param>
        /// <returns>如果处理了括号补全则返回true</returns>
        private bool AutoCompleteBracket(KeyEventArgs e)
        {
            // 如果有选中的文本，不执行自动补全
            if (AssociatedObject.TextArea.Selection.IsEmpty == false)
                return false;

            string opening = null;
            string closing = null;

            // 检测按键并确定对应的括号类型
            if (e.Key == Key.OemOpenBrackets && Keyboard.Modifiers == ModifierKeys.None)
            {
                opening = "[";
                closing = "]";
            }
            else if (e.Key == Key.OemOpenBrackets && Keyboard.Modifiers == ModifierKeys.Shift)
            {
                opening = "{";
                closing = "}";
            }
            else if (e.Key == Key.D9 && Keyboard.Modifiers == ModifierKeys.Shift)
            {
                opening = "(";
                closing = ")";
            }
            else if (e.Key == Key.OemQuotes && Keyboard.Modifiers == ModifierKeys.Shift)
            {
                opening = "\"";
                closing = "\"";
            }
            else if (e.Key == Key.OemQuotes && Keyboard.Modifiers == ModifierKeys.None)
            {
                opening = "'";
                closing = "'";
            }

            // 如果找到匹配的括号类型，执行自动补全
            if (opening != null)
            {
                var offset = AssociatedObject.CaretOffset;
                AssociatedObject.Document.Insert(offset, opening + closing);
                AssociatedObject.CaretOffset = offset + 1;
                return true;
            }

            return false;
        }
    }

    /// <summary>
    /// Tab键缩进行为，增强Tab键的功能
    /// 当有选中文本时，Tab键会缩进所有选中的行
    /// </summary>
    public class TabIndentBehavior : Behavior<TextEditor>
    {
        /// <summary>
        /// 在行为附加到编辑器时调用
        /// 添加按键预处理事件
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.TextArea.PreviewKeyDown += TextArea_PreviewKeyDown;
        }

        /// <summary>
        /// 在行为从编辑器分离时调用
        /// 移除事件处理器
        /// </summary>
        protected override void OnDetaching()
        {
            AssociatedObject.TextArea.PreviewKeyDown -= TextArea_PreviewKeyDown;
            base.OnDetaching();
        }

        /// <summary>
        /// 处理按键事件，检测是否需要处理Tab键缩进
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">按键事件参数</param>
        private void TextArea_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            // 处理Tab键进行缩进
            if (e.Key == Key.Tab)
            {
                // 如果有选中的文本，缩进所选的行
                if (!string.IsNullOrEmpty(AssociatedObject.SelectedText))
                {
                    IndentSelectedLines();
                    e.Handled = true;
                }
            }
        }

        /// <summary>
        /// 缩进所有选中的行
        /// 在每行开头添加4个空格
        /// </summary>
        private void IndentSelectedLines()
        {
            // 获取选择的起始和结束行
            int startLine = AssociatedObject.Document.GetLineByOffset(AssociatedObject.SelectionStart).LineNumber;
            int endLine = AssociatedObject.Document.GetLineByOffset(AssociatedObject.SelectionStart + AssociatedObject.SelectionLength).LineNumber;
            
            AssociatedObject.BeginChange();
            
            // 遍历每一行并添加缩进
            for (int i = startLine; i <= endLine; i++)
            {
                var line = AssociatedObject.Document.GetLineByNumber(i);
                AssociatedObject.Document.Insert(line.Offset, "    ");
            }
            
            AssociatedObject.EndChange();
        }
    }

    /// <summary>
    /// 代码完成行为，提供编辑器的代码补全功能
    /// 监听输入，并在适当时显示代码补全窗口
    /// </summary>
    public class CodeCompletionBehavior : Behavior<TextEditor>
    {
        private readonly CodeCompletionService _codeCompletionService;

        /// <summary>
        /// 初始化CodeCompletionBehavior的新实例
        /// </summary>
        public CodeCompletionBehavior()
        {
            _codeCompletionService = CodeCompletionService.Instance;
        }

        /// <summary>
        /// 在行为附加到编辑器时调用
        /// 添加文本输入和文本变化事件处理
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.TextArea.TextEntered += TextArea_TextEntered;
            AssociatedObject.TextChanged += AssociatedObject_TextChanged;
        }

        /// <summary>
        /// 在行为从编辑器分离时调用
        /// 移除事件处理器
        /// </summary>
        protected override void OnDetaching()
        {
            AssociatedObject.TextArea.TextEntered -= TextArea_TextEntered;
            AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
            base.OnDetaching();
        }
        
        /// <summary>
        /// 当编辑器文本变化时，更新代码补全服务的文本缓存
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        private void AssociatedObject_TextChanged(object sender, EventArgs e)
        {
            // 更新代码补全服务的编辑器文本
            _codeCompletionService.UpdateEditorText(AssociatedObject.Text);
        }

        /// <summary>
        /// 当用户输入文本时触发代码补全
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">文本输入事件参数</param>
        private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
        {
            // 在输入字母、数字或点号时显示自动完成
            if (char.IsLetterOrDigit(e.Text[0]) || e.Text == ".")
            {
                _codeCompletionService.ShowCompletionWindow(AssociatedObject.TextArea);
            }
        }
    }

    /// <summary>
    /// 语法高亮行为，为编辑器提供Python语法高亮功能
    /// 加载XSHD文件定义的语法规则
    /// </summary>
    public class SyntaxHighlightingBehavior : Behavior<TextEditor>
    {
        /// <summary>
        /// 定义可绑定的语法高亮文件路径依赖属性
        /// </summary>
        public static readonly DependencyProperty SyntaxHighlightingFileProperty =
            DependencyProperty.Register("SyntaxHighlightingFile", typeof(string), typeof(SyntaxHighlightingBehavior),
                new PropertyMetadata(null, OnSyntaxHighlightingFileChanged));

        /// <summary>
        /// 获取或设置语法高亮定义文件的路径
        /// </summary>
        public string SyntaxHighlightingFile
        {
            get => (string)GetValue(SyntaxHighlightingFileProperty);
            set => SetValue(SyntaxHighlightingFileProperty, value);
        }

        /// <summary>
        /// 在行为附加到编辑器时调用
        /// 尝试加载语法高亮规则
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            LoadSyntaxHighlighting();
        }

        /// <summary>
        /// 加载语法高亮规则
        /// 支持从嵌入资源或外部文件加载
        /// </summary>
        private void LoadSyntaxHighlighting()
        {
            if (string.IsNullOrEmpty(SyntaxHighlightingFile))
                return;

            try
            {
                // 首先尝试从当前目录加载
                string fullPath = SyntaxHighlightingFile;
                if (!Path.IsPathRooted(fullPath))
                {
                    fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, SyntaxHighlightingFile);
                }

                if (File.Exists(fullPath))
                {
                    using (var stream = File.OpenRead(fullPath))
                    using (var reader = new XmlTextReader(stream))
                    {
                        AssociatedObject.SyntaxHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
                    }
                    return;
                }

                // 如果文件不存在，尝试从嵌入资源加载
                var assembly = Assembly.GetExecutingAssembly();
                var resourceName = assembly.GetManifestResourceNames()
                    .FirstOrDefault(n => n.EndsWith(SyntaxHighlightingFile, StringComparison.OrdinalIgnoreCase));

                if (resourceName != null)
                {
                    using (var stream = assembly.GetManifestResourceStream(resourceName))
                    using (var reader = new XmlTextReader(stream))
                    {
                        AssociatedObject.SyntaxHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance);
                    }
                }
                else
                {
                    // 如果仍然找不到，记录警告
                    Debug.WriteLine($"警告: 找不到语法高亮文件 {SyntaxHighlightingFile}");
                }
            }
            catch (Exception ex)
            {
                // 记录语法高亮加载过程中发生的任何错误
                Debug.WriteLine($"加载语法高亮时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 当语法高亮文件属性变化时，重新加载高亮规则
        /// </summary>
        /// <param name="d">依赖对象</param>
        /// <param name="e">事件参数</param>
        private static void OnSyntaxHighlightingFileChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SyntaxHighlightingBehavior behavior)
            {
                behavior.LoadSyntaxHighlighting();
            }
        }
    }
} 